package com.xiaojie.parse.model;

import com.google.common.collect.Lists;
import lombok.Data;
import lombok.ToString;

import java.io.Serializable;
import java.lang.reflect.Field;
import java.util.*;

/**
 * @author wangye
 * @classname DataModel
 * @date 2021/6/25 14:01
 **/
@Data
@ToString
public class DataModel implements Serializable {

    private static final long serialVersionUID = 2928932667433687442L;

    //系统名称
    private String systemName;
    //导出生成压缩包内的文件名称,导入时根据此文件名超找对应的文件
    private String fileName;
    //全局配置
    private Settings settings;
    //数据表
    private LinkedHashMap<String, Table> tables;
    //表中的字段被关联{tableName:[filed1,filed2,....]}
    // <被关联表名, set<被关联字段>>
    private Map<String, Set<String>> refFieldsMap;
    //其他系统表
    private Map<String, RelOtherSystem> relOtherSystem;
    //引用文件地址
    private Set<String> refFilePaths = new HashSet<>();


    /**
     * 合并全局和表级Setting,相同配置表级优先级高
     *
     * @Author: wangye
     * @Date: 2023/9/21 9:47
     * @return:
     **/
    public void mergeSetting() throws IllegalAccessException {
        Settings globalSettings = this.getSettings();
        if (globalSettings == null) {
            return;
        }

        this.fileName = globalSettings.getFileName();

        for (Table table : this.getTables().values()) {
            Settings tableSettings = table.getSettings() == null ? new Settings() : table.getSettings();
            List<String> excludeGlobalSettingItems = Optional.ofNullable(
                            tableSettings.getExcludeGlobalSettingItems())
                    .orElse(Lists.newArrayList());
            for (Field field : Settings.class.getDeclaredFields()) {
                String fieldName = field.getName();
                if (excludeGlobalSettingItems.contains(fieldName)) {
                    continue;
                }
                Settings.Merge settingMerge = Settings.SETTING_ITEM_MERGE_MAP.get(fieldName);
                if (settingMerge == null) {
                    continue;
                }
                field.setAccessible(true);
                Object mergedValue = settingMerge.merge(field.get(globalSettings), field.get(tableSettings));
                field.set(tableSettings, mergedValue);

            }
            table.setSettings(tableSettings);
        }
    }


}
